

import java.util.StringTokenizer;

import ij.IJ;
import ij.ImagePlus;
import ij.Macro;
import ij.WindowManager;
import ij.plugin.PlugIn;
import ij.process.FloatProcessor;

public class Butterworth_Filters implements PlugIn {
	public static int LOW_PASS=0,HIGH_PASS=1;
	public static int count=0;
	int n,d,width,height, type;
	@Override
	public void run(String arg0) {
		String args=Macro.getOptions();
		
		try {
			count++;
			StringTokenizer tokenizer=new StringTokenizer(args);
			n=Integer.parseInt(tokenizer.nextToken());
			d=Integer.parseInt(tokenizer.nextToken());
			width=Integer.parseInt(tokenizer.nextToken());
			height=width;
			type=Integer.parseInt(tokenizer.nextToken());
		} catch (Exception e) {
			n=2;
			d=50;
			width=512;
			height=512;
			type=HIGH_PASS;
		}
		IJ.run("New...", String.format("name='Filter%d' type='32-bit' width=%d height=%d",count,width,height));
		ImagePlus imp=WindowManager.getCurrentImage();
		FloatProcessor processor=(FloatProcessor) imp.getProcessor();
		float[] pixels=(float[])processor.getPixels();
		int offset,p;
		for(int y=0; y<height; y++)
		{
			offset=y*width;
			for(int x=0; x<width;x++){
				p=offset+x;
				if (type==LOW_PASS) {
					pixels[p]=(float)calcLowPassValue(x, y);
				}else if (type==HIGH_PASS) {
					pixels[p]=(float)calcHighPassValue(x, y);
				}
			}
			
		}
		imp.setProcessor(null, processor);
		imp.updateImage();
	}
	
	private double calcHighPassValue(int x, int y){
		double value;
		int xcenter = (width/2)+1;
        int ycenter = (height/2)+1;
        double distance = 0;
        distance = (x-xcenter)*(x-xcenter)+(y-ycenter)*(y-ycenter);
        distance = Math.sqrt(distance);
        double parz = Math.pow(d/distance,2*n);
        value = (1/(1+parz));
		return value;
	}
	private double calcLowPassValue(int x, int y){
		double value;
		int xcenter = (width/2)+1;
        int ycenter = (height/2)+1;
        double distance = 0;
        distance = (x-xcenter)*(x-xcenter)+(y-ycenter)*(y-ycenter);
        distance = Math.sqrt(distance);
        double parz = Math.pow(distance/d,2*n);
        value = (1/(1+parz));
		return value;
	}
	

}
